use crate::mapper;
use sea_orm::{ActiveValue, DatabaseConnection, DbErr, DeleteResult};
use sky_common::constant;
use sky_pojo::{
    dto::{self, category, dish::DishPageQueryDTO},
    entities::dish,
    vo::{dish::DishVO, PageResult},
};

pub async fn save_with_flavor(
    db: DatabaseConnection,
    creator: i64,
    dto: dto::dish::DishDTO,
) -> Result<i64, String> {
    let model = dish::ActiveModel {
        name: dto
            .name
            .map(ActiveValue::set)
            .expect("The name must be set during creation"),
        category_id: dto
            .category_id
            .map(ActiveValue::Set)
            .expect("The category_id be set during creation"),
        price: dto
            .price
            .map(ActiveValue::set)
            .expect("The price be set during creation")
            .into(),
        image: dto
            .image
            .map(ActiveValue::set)
            .expect("The image be set during creation")
            .into(),
        description: dto
            .description
            .map(ActiveValue::set)
            .unwrap_or(ActiveValue::NotSet)
            .into(),
        status: dto
            .status
            .map(ActiveValue::set)
            .unwrap_or(ActiveValue::NotSet)
            .into(),
        create_user: ActiveValue::set(Some(creator)),
        update_user: ActiveValue::set(Some(creator)),
        ..Default::default()
    };

    let model = mapper::dish::create(db.clone(), model).await.unwrap();

    let _flavors = mapper::dish::dish_flavor_insert_branches(db, dto.flavors, model.id)
        .await
        .unwrap();

    Ok(model.id)
}

// 烂代码
pub async fn modify(
    db: DatabaseConnection,
    dto: dto::dish::DishDTO,
    modifier: i64,
) -> Result<dish::Model, anyhow::Error> {
    let model = dish::ActiveModel {
        name: dto
            .name
            .map(ActiveValue::Set)
            .unwrap_or(ActiveValue::NotSet)
            .into(),
        category_id: dto
            .category_id
            .map(ActiveValue::Set)
            .unwrap_or(ActiveValue::NotSet)
            .into(),
        price: dto
            .price
            .map(ActiveValue::Set)
            .unwrap_or(ActiveValue::NotSet)
            .into(),
        image: dto
            .image
            .map(ActiveValue::Set)
            .unwrap_or(ActiveValue::NotSet)
            .into(),
        description: dto
            .description
            .map(ActiveValue::Set)
            .unwrap_or(ActiveValue::NotSet)
            .into(),
        status: dto
            .status
            .map(ActiveValue::Set)
            .unwrap_or(ActiveValue::NotSet)
            .into(),
        update_user: ActiveValue::Set(Some(modifier)),
        ..Default::default()
    };

    let dish_id = match dto.id {
        Some(dish_id) => dish_id, // 提取 `Some` 中的值
        None => {
            return Err(anyhow::anyhow!("id field is required"));
        }
    };

    mapper::dish::modify_by_id(db, dish_id, model)
        .await
        .map_err(|e| anyhow::Error::msg(e.to_string()))
}

pub async fn delete_by_ids(db: DatabaseConnection, ids: Vec<i64>) -> Result<DeleteResult, DbErr> {
    mapper::dish::delete_by_ids(db, ids).await
}

pub async fn enable_disable(
    db: DatabaseConnection,
    id: i64,
    status: i32,
    modifier: i64,
) -> Result<dish::Model, DbErr> {
    let model = dish::ActiveModel {
        status: ActiveValue::set(Some(status)),
        update_user: ActiveValue::set(Some(modifier)),
        ..Default::default()
    };
    mapper::dish::modify_by_id(db, id, model).await
}

pub async fn find_by_id_with_flavor(db: DatabaseConnection, id: i64) -> Result<DishVO, String> {
    let model = mapper::dish::find_by_id(db.clone(), id).await.unwrap();

    let mut vo: DishVO = DishVO::from(model);

    let mut flavors = mapper::dish::find_flavors_by_dish_id(db.clone(), id)
        .await
        .unwrap();

    // let mut category_name = mapper::category::

    vo.flavors.append(&mut flavors);

    Ok(vo)
}

pub async fn find_by_category(
    db: DatabaseConnection,
    category_id: i64,
) -> Result<Vec<dish::Model>, DbErr> {
    mapper::dish::find_by_category(db, category_id).await
}

pub async fn query(
    db: DatabaseConnection,
    dto: DishPageQueryDTO,
) -> Result<PageResult<dish::Model>, DbErr> {
    mapper::dish::query(db, dto).await
}

pub async fn list_with_flaovr(
    db: DatabaseConnection,
    dish: dto::dish::DishFlavorDTO,
) -> Result<Vec<DishVO>, DbErr> {
    use mapper::dish::DishFlavorMapper;

    let mapper = DishFlavorMapper {
        name: None,
        category_id: dish.category_id,
        status: constant::status::ENABLE,
    };

    let dishlist = mapper::dish::list(db.clone(), mapper).await.unwrap();

    let mut dish_vo_list: Vec<DishVO> = Vec::new();

    for dish in dishlist {
        let mut dishvo = DishVO::from(dish.clone());

        let mut flavors = mapper::dish::find_flavors_by_dish_id(db.clone(), dish.id)
            .await
            .unwrap();

        dishvo.flavors.append(&mut flavors);
        dish_vo_list.push(dishvo);
    }

    Ok(dish_vo_list)
}
